package com.cdeledu.一个线程罢工的诡异事件;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

//第一个任务没啥好说的，就是简单的打印。
//第二个任务会对一个数进行累加，加到 10 之后就抛出一个未捕获的异常。
//发现当任务中抛出一个没有捕获的异常时，线程池中的线程就会处于 waiting 状态。
/**
 * 源码分析：
 * 发现线程池已经帮我们做了异常捕获，但依然会往上抛。(1149行)
 * 线程池中的任务都会被包装为一个内部 Worker 对象执行。
 * 在 finally 块中会执行 processWorkerExit(w,completedAbruptly) 方法。processWorkerExit 可以简单的理解为是把当前运行的线程销毁（最后的finally代码，里面执行了 workers.remove(w)）、同时新增（ addWorker()）一个 Worker 对象接着处理；
 * 就像是哪个零件坏掉后重新换了一个新的接着工作，但是旧零件负责的任务就没有了。
 *
 * 接下来看看 addWorker() 做了什么事情：
只看这次比较关心的部分；添加成功后会直接执行他的 start() 的方法。
由于 Worker 实现了 Runnable 接口，所以本质上就是调用了 runWorker() 方法。
在 runWorker() 其实就是上文 ThreadPoolExecutor 抛出异常时的那个方法。(1149行)
它会从队列里一直不停的获取待执行的任务，也就是 getTask()；在 getTask 也能看出它会一直从内置的队列取出任务，而一旦队列是空的，它就会 waiting 在 workQueue.take()，也就是我们从堆栈中发现的 1074 行代码。

线程名字的变化：
上文还提到了异常后的线程名称发生了改变，其实在 addWorker() 方法中可以看到 newWorker()时就会重新命名线程的名称，默认就是把后缀的计数+1。
这样一切都能解释得通了，真相只有一个：
在单个线程的线程池中一但抛出了未被捕获的异常时，线程池会回收当前的线程并创建一个新的 Worker；
它也会一直不断的从队列里获取任务来执行，但由于这是一个消费线程，根本没有生产者往里边丢任务，所以它会一直 waiting 在从队列里获取任务处，所以也就造成了线上的队列没有消费，业务线程池没有执行的问题。
 * @author zhangsulei
 *
 */
public class Demo {

	public static void main(String[] args) throws InterruptedException {
		ExecutorService execute = new ThreadPoolExecutor(1, 1, 0l, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
		execute.execute(new Runnable(){
			@Override
			public void run(){
				System.out.println("=====11==========");
			}
		});

		TimeUnit.SECONDS.sleep(1);

		execute.execute(new Run1());

	}

	private static class Run1 implements Runnable {
		@Override
		public void run(){
			int count = 0;
			while(true){
				count++;
				System.out.println(Thread.currentThread().getName() + "=====22==========" + count);
				if(count == 10){
					System.out.println(1/0);
				}

				if(count == 20){
					System.out.println("=====33==========" + count);
					break;
				}
			}
		}
	}

}

